/**
 * ==================================================
 *  @file NoHeadLinkListStack.c
 *  @desc 基于单链表实现的栈结构（链式栈）：支持 push、pop、peek、isEmpty、打印操作
 *        栈顶始终指向链表头部，遵循 LIFO（后进先出）规则
 *  @author WangBlue(wangjiping596@gmail.com)
 *  @date 2025-08-02 16:20
 *  @version 1.0
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

// =========================== 节点结构定义 ===========================

/**
 * @brief 单链表栈结点结构体
 *        每个结点包含数据域与指向下一个节点的指针
 */
typedef struct singleLinkListStack {
    int data;                               ///< 存储的数据值
    struct singleLinkListStack *next;      ///< 指向下一个节点的指针
} stackNode;

// =========================== 栈操作函数 ===========================

/**
 * @brief 创建一个新结点
 * @param value 要存储的值
 * @return 成功返回新节点指针，失败返回 NULL
 */
stackNode* createNode(int value) {
    stackNode* node = (stackNode *) malloc(sizeof(stackNode));
    if (node == NULL) return NULL;     // 内存分配失败
    node->data = value;
    node->next = NULL;
    return node;
}

/**
 * @brief 判断栈是否为空
 * @param s 栈顶指针
 * @return 若为空返回 true，否则 false
 */
bool isEmpty(stackNode *s) {
    return s == NULL;
}

/**
 * @brief 入栈操作，将新结点插入到栈顶（链表头部）
 * @param s 栈顶指针的地址（指针的指针）
 * @param value 要压入栈的值
 */
void push(stackNode **s, int value) {
    stackNode *node = createNode(value);
    if (node == NULL) return;          // 内存分配失败
    node->next = *s;                   // 新节点指向旧栈顶
    *s = node;                         // 更新栈顶
}

/**
 * @brief 出栈操作，弹出栈顶元素并释放内存
 * @param s 栈顶指针的地址
 * @return 若栈空返回 -1，否则返回栈顶值
 */
int pop(stackNode **s) {
    if (isEmpty(*s)) return -1;        // 栈空
    stackNode *top = *s;               // 记录当前栈顶节点
    int value = top->data;
    *s = top->next;                    // 栈顶下移
    free(top);                         // 释放原栈顶节点
    return value;
}

/**
 * @brief 查看栈顶元素但不弹出
 * @param s 栈顶指针的地址
 * @return 若栈空返回 -1，否则返回栈顶值
 */
int peek(stackNode **s) {
    if (isEmpty(*s)) return -1;
    return (*s)->data;
}

/**
 * @brief 打印栈中所有元素（从栈顶到栈底）
 * @param s 栈顶指针的地址
 */
void printStack(stackNode **s) {
    if (isEmpty(*s)) return;
    stackNode *cur = *s;
    while (cur != NULL) {
        printf("value is %d\n", cur->data);
        cur = cur->next;
    }
    printf("\n");
}



// =========================== 主函数测试 ===========================

int main() {
    stackNode *stack = NULL;           // 初始化空栈（栈顶为 NULL）

    // 压入数据
    push(&stack, 10);
    push(&stack, 20);
    push(&stack, 30);                  // 栈顶：30 -> 20 -> 10

    printf("top is %d\n", peek(&stack)); // 输出当前栈顶值：30
    printf("\n");

    printStack(&stack);                // 打印整个栈内容：30, 20, 10

    return 0;
}
